#ifndef MY_STACK_H
#define MY_STACK_H

#include <cassert>
#include <cstdio>

template <typename T>
struct Node
{
	T m_value;
	Node* m_pNextNode;
};

template <typename T>
class MyStack
{
public:
	MyStack():m_size(0),m_pHead(NULL){};
	~MyStack();
public:
	bool isEmpty(void);
	T getSize(void);
	void push(T value);
	T pop(void);
	T getHead(void);
private:
	Node<T>* m_pHead;
	int m_size;
};


template<typename T> 
MyStack<T>::~MyStack()
{
	while (this->m_pHead!=NULL)
	{
		Node<T>* tempNode = m_pHead->m_pNextNode;
		delete m_pHead;
		m_pHead = tempNode;
	}
}

template<typename T> 
bool MyStack<T>::isEmpty(void)
{
	return m_size==0? true:false;
}

template<typename T> 
T MyStack<T>::getSize(void)
{
	return m_size;
}

template<typename T> 
void MyStack<T>::push(T value)
{
	++m_size;
	if(this->isEmpty())
	{
		m_pHead->m_value = value;
		m_pHead->m_pNextNode = NULL;	
	}
	else
	{
		Node<T>* newNode = new Node<T>;
		newNode->m_value = value;
		newNode->m_pNextNode = m_pHead;
		m_pHead = newNode;
	}
}

template<typename T> 
T MyStack<T>::pop(void)
{
	assert(!this->isEmpty());

	T value = m_pHead->m_value;
	Node<T>* nextNode = m_pHead->m_pNextNode;
	delete m_pHead;
	m_pHead = nextNode;
	--m_size;

	return value;
}

template<typename T> 
T MyStack<T>::getHead(void)
{
	return m_pHead->m_value;
}

#endif